{
  // async 函数中使用 await VS return VS return await 的异同

  async function waitAndMaybeReject() {
    // 执行耗时一秒钟
    await new Promise((r) => setTimeout(r, 1000));
    // 掷硬币
    const isHeads = Boolean(Math.round(Math.random()));

    if (isHeads) return 'yay'; // 一半成功
    throw new Error('Boo!'); // 一半抛错
  }

  async function foo() {
    await waitAndMaybeReject();
  }
  // 1 awai会暂停当前函数foo，等待promise处理完成；
  // 2 如果promise正常处理（fullilled），其回调的resolve函数将作为await表达式的值，接着继续执行async function foo；
  // 3 如果promise异常，await会把异常原因抛出；
  // 4 另外，如果await操作符后的表达式不是promise，则返回值本身

  // 🍌🍌🍌 没有await 🍌🍌🍌
  async function foo1() {
    try {
      waitAndMaybeReject();
    } catch (e) {
      return 'caught';
    }
  }
  // 结果：立马返回undefined。
  // 分析：执行 foo1时，由于 waitAndMaybeReject 是异步函数，所以try...catch只能捕获到同步的错误，所以最终啥也没闹到，最后返回 undefined。

  // 🍌🍌🍌 await 🍌🍌🍌
  async function foo2() {
    try {
      await waitAndMaybeReject();
    } catch (e) {
      return 'caught';
    }
  }
  // 结果：
  // 结果1秒钟后返回；
  // waitAndMaybeReject 成功时，return undefined;
  // waitAndMaybeReject 失败时，return 'caught'
  // 分析：
  // await 和 async 联合使用，是一个串行的异步函数；
  // waitAndMaybeReject 成功时，只执行 try 块区域，由于没有返回值，所以默认返回 undefined;
  // waitAndMaybeReject 失败时，会抛出错误，catch 块区域捕获到错误内容，返回 'caught'。

  // 🍌🍌🍌 return 🍌🍌🍌
  async function foo3() {
    try {
      return waitAndMaybeReject();
    } catch (e) {
      return 'caught';
    }
    console.log(4); // 不会被执行
  }
  // 由于这里直接将函数 waitAndMaybeReject return 了出去，所以后面的内容都不会被执行！(例如上面的console.log(4))

  // 结果：
  // 结果1秒钟后返回；
  // waitAndMaybeReject 成功时，return 'yay'，函数 foo3 执行结束;
  // waitAndMaybeReject 失败时，抛出错误 Error('Boo!')，函数 foo3 执行被终止。【异常 未捕获】

  // 分析：
  // await 和 async 联合使用，是一个串行的异步函数；
  // waitAndMaybeReject 成功时，只执行 try 块区域，return 获取到的是 'yay'，所以返回 'yay';
  // waitAndMaybeReject 失败时，return 获取到抛出的错误，函数执行被终止，catch 块区域不会捕获到错误。

  // 🍌🍌🍌 return await 🍌🍌🍌
  async function foo4() {
    try {
      // const res = await waitAndMaybeReject();
      // return res
      return await waitAndMaybeReject(); // 和上面写法等价
    } catch (e) {
      return 'caught';
    }
  }
  // 结果：
  // 结果1秒钟后返回；
  // waitAndMaybeReject 成功时，return 'yay';
  // waitAndMaybeReject 失败时，return 'caught'.
  // 分析：
  // await 和 async 联合使用，是一个串行的异步函数；
  // waitAndMaybeReject 成功时，只执行 try 块区域，fulfilledValue 的值是 'yay'，所以最终返回 'yay';
  // waitAndMaybeReject 失败时，try 块区域的 fulfilledValue 获取的是抛出的错误，catch 捕获错误，最终返回 'caught'。【异常被捕获】
  //
  // 特别提示：return await 只有在 try...catch 中可行，否则会报 eslint 冗余的错误。

  // 测试
  var test = async () => {
    console.log('pare');
    console.log(await foo1());
    console.log('await');
    console.log(await foo2());
    console.log('return');
    console.log(await foo3());
    console.log('return await');
    console.log(await foo4());
  };
  test();
}
